package sharewithus.analyzer.tag;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.StringTokenizer;

import sharewithus.analyzer.PartOfSpeech;

/**
 * 词性转移概率表
 * 
 * @author terry
 * 
 */
public class POSContextState implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -3244884555257735732L;

	private static final String TRANS_DIC = "/sharewithus/analyzer/tag/TransProbility.txt";

	private static int[][] transProbs;

	private static int[] posProbs;

	private static int frqCount;

	private static final POSContextState cs = new POSContextState();

	public static POSContextState getInstance() {
		return cs;
	}

	private POSContextState() {
		int matrixLength = PartOfSpeech.values().length;
		// System.out.println(matrixLength);
		posProbs = new int[matrixLength];
		transProbs = new int[matrixLength][];

		for (int i = 0; i < PartOfSpeech.values().length; ++i)
			transProbs[i] = new int[matrixLength];
		InputStream ins = POSContextState.class
		.getResourceAsStream(POSContextState.TRANS_DIC);
		if (ins == null) {
			throw new RuntimeException("TransProb file not found!!!");
		}
		BufferedReader read;
		try {
			
		    	read = new BufferedReader(new InputStreamReader(ins,
					"UTF-8"));
			String line = null;
			// Integer frqCount = 0; /* 词性量 */
			int i = 0; /* 转移概率表的横坐标 */
			int j = 0; /* 转移概率表的纵坐标 */

			/* 获取语料库中词性的数量 */
			line = read.readLine();
			if (line == null)
				return;
			frqCount = Integer.parseInt(line);
			/* 设置各种词性频率 */
			for (int k = 0; k < frqCount; k++) {
				line = read.readLine();
				posProbs[k] = Integer.parseInt(line.split(":")[1]);
				// System.out.println(posProbs[k]);
			}

			// 填充词性转换频率矩阵
			while ((line = read.readLine()) != null) {
				// System.out.println(line);
				StringTokenizer st = new StringTokenizer(line, " ");

				int count = st.countTokens();
				for (j = 0; j < count; j++) {
					String s = st.nextToken();
					transProbs[i][j] = Integer.valueOf(s);
				}
				i++;
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void addTrob(PartOfSpeech prev, PartOfSpeech cur, int val) {
		transProbs[prev.ordinal()][cur.ordinal()] = val;
	}

	/**
	 * 获取转移概率
	 * 
	 * @param prev 前一个词性
	 * @param cur 后一个词性
	 * @return 转移概率
	 */
	public double getTransProb(PartOfSpeech prev, PartOfSpeech cur) {
		return Math
				.log((double) (transProbs[prev.ordinal()][cur.ordinal()] + 1)
						/ (double) (posProbs[prev.ordinal()] + frqCount));
	}

	public double getTransFreq(PartOfSpeech prev, PartOfSpeech cur) {
		/*System.out.println(prev + " to " + cur + ":"
				+ transProbs[prev.ordinal()][cur.ordinal()]);*/
		return (double) (transProbs[prev.ordinal()][cur.ordinal()] + 1)
				/ (double) (posProbs[prev.ordinal()] + frqCount);
	}

	/**
	 * 获取发射概率
	 * 
	 * @param pos 词性
	 * @param w 频率
	 * @return 发射概率
	 */
	public double getEmiprob(PartOfSpeech pos, double w) {
		return Math
				.log((w==0?1:w)
						/ (double) (posProbs[pos.ordinal()] + PartOfSpeech
								.values().length));
	}

	public double getEmiFreq(PartOfSpeech pos, double w) {
		return w
				/ (double) (posProbs[pos.ordinal()] + PartOfSpeech.values().length);
	}

	public int[][] getTransProbs() {
		return transProbs;
	}

}
